package com.hn.common.exception;

import com.hn.framework.web.domain.AjaxResult;
import com.hn.common.enums.ResultCode;
import com.hn.common.utils.CommonUtils;
import com.taobao.api.ApiException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 描述:
 * 全局异常处理
 *
 * @date 2019-11-14 17:33
 */
public class GlobalExceptionResolver implements HandlerExceptionResolver {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionResolver.class);

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
        AjaxResult result = new AjaxResult();
        if (e instanceof BusinessException || e instanceof DingException) {
            result = AjaxResult.error(ResultCode.FAIL, e.getMessage());
        } else if (e instanceof NoHandlerFoundException) {
            result = AjaxResult.error(ResultCode.NOT_FOUND, "接口 [" + request.getRequestURI() + "] 不存在");
        } else if (e instanceof LoginException) {
            result = AjaxResult.error(ResultCode.UNAUTHORIZED, e.getMessage());
        } else if (e instanceof ImgCodeException) {
            result = AjaxResult.error(ResultCode.FAIL, e.getMessage());
        } else if (e instanceof ServletException) {
            result = AjaxResult.error(ResultCode.FAIL, e.getMessage());
        } else if (e instanceof IllegalArgumentException || e instanceof MsgCodeException) {
            result = AjaxResult.error(ResultCode.FAIL, e.getMessage());
        } else if(e instanceof ApiException){
            result = AjaxResult.error(ResultCode.FAIL,((ApiException) e).getErrMsg());
        } else if (e instanceof BadSqlGrammarException) {
            String errMsg = e.getMessage();
            if (errMsg.contains("'order clause'")) {
                String[] strings = errMsg.split("'");
                result = AjaxResult.error(ResultCode.FAIL, "查询数据库失败:排序字段有误:" + strings[1]);
            } else {
                result = AjaxResult.error(ResultCode.FAIL, "查询数据库失败:请联系管理员");
            }
        } else if (e instanceof MethodArgumentNotValidException) {
            FieldError fieldError = ((MethodArgumentNotValidException) e).getBindingResult().getFieldError();
            assert fieldError != null;
            logger.error(fieldError.getField() + ":" + fieldError.getDefaultMessage());
            result = AjaxResult.error(ResultCode.FAIL, fieldError.getDefaultMessage());
        } else {
            result = AjaxResult.error(ResultCode.INTERNAL_SERVER_ERROR, "接口 [" + request.getRequestURI() + "] 内部错误，请联系管理员");
            String message;
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                message = String.format("接口 [%s] 出现异常，方法：%s.%s，异常摘要：%s",
                        request.getRequestURI(),
                        handlerMethod.getBean().getClass().getName(),
                        handlerMethod.getMethod().getName(),
                        e.getMessage());
            } else {
                message = e.getMessage();
            }
            logger.error(e.getMessage(), message);
        }
        logger.error(e.getMessage(), e.fillInStackTrace());
        CommonUtils.responseResult(response, result);
        return new ModelAndView();
    }
}
